package cn.kent.service;

import cn.kent.common.Message;
import cn.kent.common.MessageStorage;
import cn.kent.common.MessageType;
import cn.kent.common.User;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 这是服务器，监听9999，等待客户端连接，并保持通信
 */
public class QQServer {
    private ServerSocket serverSocket = null;
    // 创建一个集合，存放多个用户，如果是这些用户登录，就认为是合法的
    private static ConcurrentHashMap<String, User> validUsers = new ConcurrentHashMap<>();

    static {
        validUsers.put("100", new User("100", "123456"));
        validUsers.put("200", new User("200", "123456"));
        validUsers.put("300", new User("300", "123456"));
        validUsers.put("太上老君", new User("太上老君", "123456"));
    }

    /**
     * 验证用户是否有效
     */
    private boolean checkUser(String userId, String passwd) {
        User user = validUsers.get(userId);
        if (user == null) {// 账号不存在
            return false;
        }
        // 密码是否正确
        return user.getPasswd().equals(passwd);
    }

    public QQServer() {
        try {
            System.out.println("服务端在9999端口监听。。。");

            new Thread(new SendNewsToAllService()).start();
            serverSocket = new ServerSocket(9999);

            while (true) {
                Socket socket = serverSocket.accept(); // 如果没有客户端连接，就阻塞在这
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                User u = (User) ois.readObject();
                Message message = new Message();
                // 验证
                if (checkUser(u.getUserId(), u.getPasswd())) { // 登录通过
                    message.setMsgType(MessageType.MESSAGE_LOGIN_SUCCEE);
                    oos.writeObject(message);
                    // 创建一个线程，和客户端保持通信，该线程持有socket对象
                    ServerConnectClientThread serverConnectClientThread = new ServerConnectClientThread(socket, u.getUserId());
                    serverConnectClientThread.start();
                    // 将线程放入到集合中进行管理
                    ManageClientThreads.addClientThread(u.getUserId(), serverConnectClientThread);

                    // 判断是否有离线消息，作相应转发
                    List<Message> ms = MessageStorage.getMessageStorage(u.getUserId());
                    if (ms != null && ms.size() > 0) {
                        for (Message m : ms) {
                            ObjectOutputStream oos2 = new ObjectOutputStream(socket.getOutputStream());
                            oos2.writeObject(m);
                        }
                    }
                } else {// 登录失败
                    System.out.println(u.getUserId() + "登录失败[服务端验证]");
                    message.setMsgType(MessageType.MESSAGE_LOGIN_FAIL);
                    oos.writeObject(message);
                    // 关闭socket
                    socket.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 如果服务端退出了while循环，说明服务端不再监听，因此关闭serverSocket
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
